package io.mft.datasource.db.accessor.util;

import java.sql.SQLException;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.PageResult;
import cn.hutool.db.sql.Direction;
import cn.hutool.db.sql.Order;
import io.mft.commons.db.mapper.SQLExecutorDbMapper;
import io.mft.commons.db.mapper.TableDbMapper;
import io.mft.commons.function.response.kv.KVMap;
import io.mft.commons.function.response.kv.PageObject;

public class PageLoader {
	public static <T> PageObject<T> page(String datasourceId,String tbName,Class<T> kClass, T parameter,int pageNo,
			int pageSize,String...descOrderby) throws SQLException {
		if (pageSize<=0) {
			pageSize=100;
		}
		TableDbMapper<T> mapper=TableDbMapper.getInstance(datasourceId, tbName, kClass);
		cn.hutool.db.Page hutoolpage=new cn.hutool.db.Page(pageNo, pageSize);
		for (String order : descOrderby) {
			if (ObjectUtil.isEmpty(order)) {
				continue;
			}
			OrderBy orderBy=new OrderBy(order);
			if (orderBy.available()) {
				hutoolpage.addOrder(orderBy.order);
			}
			
		}
		
		PageResult<T> pageResult=mapper.page(parameter, hutoolpage,true);
		PageObject<T> pageObject=new PageObject<>(pageNo, pageSize, pageResult.getTotal());
		pageObject.getList().addAll(pageResult);
		return pageObject;
	}
	public static PageObject<KVMap> page(String datasourceId,String tbName, KVMap parameter,int pageNo,
			int pageSize,String...descOrderby) throws SQLException {
		PageObject<KVMap> pageObject=page(datasourceId, tbName, KVMap.class, parameter, pageNo, pageSize, descOrderby);
		return pageObject;
	}
	public static  PageObject<KVMap> pageBysql(String datasourceId,String sql, Object[] parameter,int pageNo,
			int pageSize) throws SQLException {
		PageObject<KVMap> pageObject=pageBysql(datasourceId, sql, parameter, KVMap.class, pageNo, pageSize);
		return pageObject;
	}
	
	public static  PageObject<KVMap> pageBysqlfunction(String datasourceId,String sql, Object[] parameter,int pageNo,
			int pageSize) throws SQLException {
		PageObject<KVMap> pageObject=pageBysqlfunction(datasourceId, sql, parameter, KVMap.class, pageNo, pageSize);
		return pageObject;
	}
	public static  PageObject<KVMap> pageBysqlprocedure(String datasourceId,String sql,String[] paramTypes, Object[] parameter,int pageNo,
			int pageSize) throws SQLException {
		PageObject<KVMap> pageObject=pageBysqlprocedure(datasourceId, sql,paramTypes, parameter, KVMap.class, pageNo, pageSize);
		return pageObject;
	}
	public static <T> PageObject<T> pageBysqlfunction(String datasourceId,String sql, Object[] parameter,Class<T> kClass,int pageNo,
			int pageSize) throws SQLException {
		if (pageSize<=0) {
			pageSize=100;
		}
		SQLExecutorDbMapper<T> mapper=SQLExecutorDbMapper.getInstance(datasourceId, kClass);
		cn.hutool.db.Page hutoolpage=new cn.hutool.db.Page(pageNo, pageSize);
		PageResult<T> pageResult=mapper.executePageFunction(sql, hutoolpage, parameter);
		PageObject<T> pageObject=new PageObject<>(pageNo, pageSize, pageResult.getTotal());
		pageObject.getList().addAll(pageResult);
		return pageObject;
	}
	public static <T> PageObject<T> pageBysqlprocedure(String datasourceId,String sql,String[] paramTypes, Object[] parameter,Class<T> kClass,int pageNo,
			int pageSize) throws SQLException {
		if (pageSize<=0) {
			pageSize=100;
		}
		SQLExecutorDbMapper<T> mapper=SQLExecutorDbMapper.getInstance(datasourceId, kClass);
		cn.hutool.db.Page hutoolpage=new cn.hutool.db.Page(pageNo, pageSize);
		PageResult<T> pageResult=mapper.executePageProcedure(sql, hutoolpage, paramTypes,parameter);
		PageObject<T> pageObject=new PageObject<>(pageNo, pageSize, pageResult.getTotal());
		pageObject.getList().addAll(pageResult);
		return pageObject;
	}
	public static <T> PageObject<T> pageBysql(String datasourceId,String sql, Object[] parameter,Class<T> kClass,int pageNo,
			int pageSize) throws SQLException {
		if (pageSize<=0) {
			pageSize=100;
		}
		SQLExecutorDbMapper<T> mapper=SQLExecutorDbMapper.getInstance(datasourceId, kClass);
		cn.hutool.db.Page hutoolpage=new cn.hutool.db.Page(pageNo, pageSize);
		PageResult<T> pageResult=mapper.pageBySql(sql, hutoolpage, parameter);
		PageObject<T> pageObject=new PageObject<>(pageNo, pageSize, pageResult.getTotal());
		pageObject.getList().addAll(pageResult);
		return pageObject;
	}
	
	
	static class OrderBy{
		Order order;
		public OrderBy(String orderBy) {
			//a.alias_key desc
			if (ObjectUtil.isNotEmpty(orderBy)) {
				try {
					String[] as=orderBy.split(" ");
					String field=StrUtil.toUnderlineCase(as[0]);
					String direction=as[as.length-1];
					order=new Order(field, Direction.fromString(direction));
				} catch (Exception e) {
					// TODO: handle exception
				}

			}

		}
		public Order getOrder() {
			return order;
		}
		public boolean available() {
			return order==null?false:true;
		}
	}
}
